namespace System.Xml.Serialization
{
    using System;
    using System.IO;
    using System.IO.IsolatedStorage;

    [Serializable]
    public class XmlIsolatedStorageSerializer<T> : XmlFileStreamSerializer<T>
    {
        private string GetFileName(IsolatedStorageFile file, string fileName)
        {
            string[] files = file.GetFileNames(fileName);
            if ((files != null) && (files.Length == 1))
            {
                return files[0];
            }
            return null;
        }

        protected override T Deserialize(string fileName, IXmlTypeFormatter formatter)
        {
            lock (((XmlIsolatedStorageSerializer<T>)this))
            {
                try
                {
                    IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
                    using (Stream stream = new IsolatedStorageFileStream(GetFileName(file, fileName), FileMode.Open, FileAccess.Read, FileShare.None, file))
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            stream.BlockCopy(ms);
                            ms.Position = 0;
                            return InternalStreamDeserialize(ms, formatter);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new XmlSerializationException();
                    //PluginLog.WriteErrorSync(ex);
                }
            }
        }

        protected override void Serialize(string fileName, T obj, IXmlTypeFormatter formatter)
        {
            lock (((XmlIsolatedStorageSerializer<T>)this))
            {
                try
                {
                    IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
                    using (Stream stream = new IsolatedStorageFileStream(GetFileName(file, fileName), FileMode.Create, FileAccess.Write, FileShare.None, file))
                    {
                        using (MemoryStream ms = InternalStreamSerialize(obj, formatter))
                        {
                            ms.Position = 0;
                            ms.BlockCopy(stream);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new XmlSerializationException();
                    //PluginLog.WriteErrorSync(ex);
                }
            }
        }
    }

    public static class StreamHelper
    {
        public static void Copy(Stream source, Stream target, int blockSize)
        {
            int read;
            byte[] buffer = new byte[blockSize];
            while ((read = source.Read(buffer, 0, blockSize)) > 0)
            {
                target.Write(buffer, 0, read);
            }
        }
        public static void BlockCopy(this Stream source, Stream target, int blockSize = 65536)
        {
            Copy(source, target, blockSize);
        }
    }
}

